package no.nordicsemi.android.nrfmesh.auth.ui.account;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import no.nordicsemi.android.nrfmesh.R;
import no.nordicsemi.android.nrfmesh.auth.data.AuthRepository;
import no.nordicsemi.android.nrfmesh.auth.data.db.Account;
import no.nordicsemi.android.nrfmesh.auth.data.db.DoctorProfile;
import no.nordicsemi.android.nrfmesh.auth.data.db.UserProfile;
import no.nordicsemi.android.nrfmesh.auth.session.SessionManager;
import no.nordicsemi.android.nrfmesh.auth.ui.AuthViewModel;
import no.nordicsemi.android.nrfmesh.database.entity.LocalAccount;
import no.nordicsemi.android.nrfmesh.widgets.CustomControlsActivity;
import no.nordicsemi.android.nrfmesh.widgets.UserMainActivity;

public class SwitchAccountDialogFragment extends DialogFragment {

    private static final String TAG = "SwitchAccountDlg";

    public static SwitchAccountDialogFragment newInstance() { return new SwitchAccountDialogFragment(); }

    private AuthViewModel authVM;
    private ArrayAdapter<String> adapter;
    private final List<String> displayRows = new ArrayList<>(); // 形如："d12345 (DOCTOR)"
    private final List<String> userIds     = new ArrayList<>(); // 与 displayRows 对应

    @NonNull @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        authVM = new ViewModelProvider(requireActivity()).get(AuthViewModel.class);

        try {
            no.nordicsemi.android.nrfmesh.auth.data.AccountRepository repo = new no.nordicsemi.android.nrfmesh.auth.data.AccountRepository(
                    no.nordicsemi.android.nrfmesh.database.AppDatabase.getInstance(requireContext().getApplicationContext()).localAccountDao(),
                    new no.nordicsemi.android.nrfmesh.auth.util.CredentialStore(requireContext().getApplicationContext())
            );
            authVM.attachAccountRepo(repo);
        } catch (Throwable ignore) { }

        View v = getLayoutInflater().inflate(R.layout.dialog_switch_account, null, false);
        ListView lv = v.findViewById(R.id.lv_accounts);
        ProgressBar pb = v.findViewById(R.id.pb_switch);
        TextView tvEmpty = v.findViewById(R.id.tv_empty);

        adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, displayRows);
        lv.setAdapter(adapter);
        lv.setOnItemClickListener((p, view, pos, id) -> {
            if (pos >= 0 && pos < userIds.size()) {
                String userId = userIds.get(pos);
                Log.d(TAG, "onItemClick -> selected userId=" + userId);
                doSwitch(userId, pb);
            }
        });

        // 1) 先用快照渲染一次
        List<LocalAccount> snapshot = authVM.accounts.getValue();
        Log.d(TAG, "snapshot size=" + (snapshot == null ? "null" : snapshot.size()));
        renderAsync(snapshot, tvEmpty);

        // 2) 监听 LiveData，后续更新
        authVM.accounts.observe(requireActivity(), rows -> {
            Log.d(TAG, "accounts LiveData changed. size=" + (rows == null ? "null" : rows.size()));
            renderAsync(rows, tvEmpty);
        });

        // 3) 若快照为空，主动请求刷新
        if (snapshot == null || snapshot.isEmpty()) {
            Log.d(TAG, "snapshot empty -> authVM.loadAccounts()");
            authVM.loadAccounts();
        }

        return new AlertDialog.Builder(requireContext())
                .setTitle("切换账户")
                .setView(v)
                .setNegativeButton("关闭", null)
                .create();
    }

    /** 后台构造显示行：userId + (ROLE?)；主线程更新 UI */
    private void renderAsync(List<LocalAccount> rows, TextView tvEmpty) {
        displayRows.clear();
        userIds.clear();
        adapter.notifyDataSetChanged();
        tvEmpty.setVisibility(View.VISIBLE);

        if (rows == null || rows.isEmpty()) {
            Log.d(TAG, "renderAsync: rows empty.");
            return;
        }

        final android.content.Context ctx = getContext();
        if (ctx == null) return;
        final android.content.Context appCtx = ctx.getApplicationContext();

        new Thread(() -> {
            Log.d(TAG, "renderAsync: start building rows in bg, count=" + rows.size());
            AuthRepository repo = new AuthRepository(appCtx);

            List<String> tmpDisplay = new ArrayList<>();
            List<String> tmpIds = new ArrayList<>();

            for (LocalAccount a : rows) {
                String uid = a.userId;
                String role = null;

                // 尝试通过反射拿 Account（如果 AuthRepository 提供了按 username 查的接口）
                try {
                    Method m = null;
                    try { m = repo.getClass().getMethod("accountByUsername", String.class); }
                    catch (NoSuchMethodException ignore) {
                        try { m = repo.getClass().getMethod("account", String.class); }
                        catch (NoSuchMethodException ignore2) { /* no-op */ }
                    }
                    if (m != null) {
                        Object accObj = m.invoke(repo, uid);
                        if (accObj instanceof Account) {
                            role = ((Account) accObj).role;
                            Log.d(TAG, "role via Account for " + uid + " = " + role);
                        }
                    }
                } catch (Throwable t) {
                    Log.d(TAG, "role reflect Account failed for " + uid + " : " + t.getClass().getSimpleName());
                }

                // 若还未知：退化为根据资料存在性判断（需要拿到 long id，无法时跳过）
                if (role == null) {
                    try {
                        Method m = repo.getClass().getMethod("account", String.class);
                        Object accObj = m.invoke(repo, uid);
                        if (accObj instanceof Account) {
                            long id = ((Account) accObj).id;
                            UserProfile up = repo.userProfile(id);
                            if (up != null) role = "USER";
                            DoctorProfile dp = repo.doctorProfile(id);
                            if (dp != null) role = "DOCTOR";
                            Log.d(TAG, "role via profile for " + uid + " = " + role);
                        }
                    } catch (Throwable t) {
                        // 忽略，保底仅显示 ID
                        Log.d(TAG, "role reflect profile failed for " + uid);
                    }
                }

                String row = role != null ? (uid + " (" + role + ")") : uid;
                tmpDisplay.add(row);
                tmpIds.add(uid);
            }

            final androidx.fragment.app.FragmentActivity act = getActivity();
            if (act == null || !isAdded()) return;
            act.runOnUiThread(() -> {
                if (!isAdded()) return;
                displayRows.clear();
                userIds.clear();
                displayRows.addAll(tmpDisplay);
                userIds.addAll(tmpIds);
                adapter.notifyDataSetChanged();
                tvEmpty.setVisibility(displayRows.isEmpty() ? View.VISIBLE : View.GONE);
                Log.d(TAG, "renderAsync: UI updated. rows=" + displayRows.size());
            });
        }).start();
    }

    /** 用保存的密码直接切换并登录 */
    private void doSwitch(String userId, ProgressBar pb) {
        String savedPwd = new ViewModelProvider(requireActivity())
                .get(AuthViewModel.class).getSavedPassword(userId);
        Log.d(TAG, "doSwitch: userId=" + userId + " savedPwd? " + (savedPwd != null));
        if (savedPwd == null) {
            final android.widget.EditText et = new android.widget.EditText(requireContext());
            et.setHint("请输入密码");
            et.setInputType(android.text.InputType.TYPE_CLASS_TEXT | android.text.InputType.TYPE_TEXT_VARIATION_PASSWORD);
            new androidx.appcompat.app.AlertDialog.Builder(requireContext())
                    .setTitle("未保存密码，无法直接切换")
                    .setMessage("请输入「" + userId + "」的密码以完成切换")
                    .setView(et)
                    .setNegativeButton("取消", null)
                    .setPositiveButton("切换", (d, w) -> {
                        String pwd = et.getText() != null ? et.getText().toString() : null;
                        if (pwd == null || pwd.length() < 6) {
                            android.widget.Toast.makeText(requireContext(), "密码至少6位", android.widget.Toast.LENGTH_SHORT).show();
                            return;
                        }
                        doSwitchWithPassword(userId, pwd, pb);
                    })
                    .show();
            return;
        }

        pb.setVisibility(View.VISIBLE);

        new Thread(() -> {
            try {
                AuthRepository repo = new AuthRepository(requireContext());
                Account acc = repo.login(userId, savedPwd.toCharArray());
                Log.d(TAG, "doSwitch: login ok. uid=" + acc.id + " role=" + acc.role);

                String displayName;
                if ("USER".equals(acc.role)) {
                    UserProfile up = repo.userProfile(acc.id);
                    displayName = up != null ? up.name : acc.username;
                } else {
                    DoctorProfile dp = repo.doctorProfile(acc.id);
                    displayName = dp != null ? dp.name : acc.username;
                }

                // 保存会话 & 通知 VM
                final androidx.fragment.app.FragmentActivity act = getActivity();
                if (act == null) return;
                act.runOnUiThread(() -> {
                    new SessionManager(act).save(acc.id, acc.role, displayName);
                    new ViewModelProvider(act).get(AuthViewModel.class)
                            .onLoginSucceeded(userId, displayName, true, true, savedPwd);

                    pb.setVisibility(View.GONE);
                    Toast.makeText(act, "已切换到：" + userId, Toast.LENGTH_SHORT).show();

                    try { dismissAllowingStateLoss(); } catch (Throwable ignore) {}
                    Class<?> target = "USER".equals(acc.role) ? UserMainActivity.class : CustomControlsActivity.class;
                    if (act.getClass().equals(target)) {
                        act.recreate();
                    } else {
                        Intent i = new Intent(act, target);
                        act.startActivity(i);
                        act.finish();
                    }
                });

            } catch (Exception e) {
                Log.e(TAG, "doSwitch: login failed: " + e.getMessage(), e);
                final androidx.fragment.app.FragmentActivity act = getActivity();
                if (act != null) act.runOnUiThread(() -> {
                    pb.setVisibility(View.GONE);
                    Toast.makeText(act, "切换失败：" + e.getMessage(), Toast.LENGTH_SHORT).show();
                });
            }
        }).start();
    }

    private void doSwitchWithPassword(String userId, String plainPwd, ProgressBar pb) {
        pb.setVisibility(View.VISIBLE);

        new Thread(() -> {
            try {
                AuthRepository repo = new AuthRepository(requireContext());
                Account acc = repo.login(userId, plainPwd.toCharArray());

                String displayName;
                if ("USER".equals(acc.role)) {
                    UserProfile up = repo.userProfile(acc.id);
                    displayName = up != null ? up.name : acc.username;
                } else {
                    DoctorProfile dp = repo.doctorProfile(acc.id);
                    displayName = dp != null ? dp.name : acc.username;
                }

                final androidx.fragment.app.FragmentActivity act = getActivity();
                if (act == null) return;
                act.runOnUiThread(() -> {
                    // 保存会话 & 记住密码，保证下次可直接切
                    new SessionManager(act).save(acc.id, acc.role, displayName);
                    new ViewModelProvider(act).get(AuthViewModel.class)
                            .onLoginSucceeded(userId, displayName, true, true, plainPwd);

                    pb.setVisibility(View.GONE);
                    android.widget.Toast.makeText(act, "已切换到：" + userId, android.widget.Toast.LENGTH_SHORT).show();

                    try { dismissAllowingStateLoss(); } catch (Throwable ignore) {}
                    Class<?> target = "USER".equals(acc.role) ? UserMainActivity.class : CustomControlsActivity.class;
                    if (act.getClass().equals(target)) {
                        act.recreate();
                    } else {
                        Intent i = new Intent(act, target);
                        act.startActivity(i);
                        act.finish();
                    }
                });

            } catch (Exception e) {
                final androidx.fragment.app.FragmentActivity act = getActivity();
                if (act != null) act.runOnUiThread(() -> {
                    pb.setVisibility(View.GONE);
                    android.widget.Toast.makeText(act, "切换失败：" + e.getMessage(), android.widget.Toast.LENGTH_SHORT).show();
                });
            }
        }).start();
    }
}
